﻿using JESAI.EventBus.Builders;
using JESAI.EventBus.EventBusStores;
using JESAI.EventBus.HostBackgroundServices;
using JESAI.EventBus.PublishManagers;
using JESAI.EventBus.SubscribeManagers;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class EventBusServiceCollectionExtensions
    {
        public static IServiceCollection AddJESAIEventBus(this IServiceCollection services, Action<EventBusOptionsBuilder> configureOptionsBuilder)
        {
            var eventBusOptionsBuilder = new EventBusOptionsBuilder();
            configureOptionsBuilder.Invoke(eventBusOptionsBuilder);

            return services.AddJESAIEventBus(eventBusOptionsBuilder);
        }

        public static IServiceCollection AddJESAIEventBus(this IServiceCollection services, EventBusOptionsBuilder eventBusOptionsBuilder = default)
        {
            if (eventBusOptionsBuilder == null)
            {
                eventBusOptionsBuilder = new EventBusOptionsBuilder();
            }

            var defaultStorerOfChannel = new ChannelEventStore(eventBusOptionsBuilder.MaxChannelCapacity, eventBusOptionsBuilder.BoundedChannelFullMode);

            services.AddSingleton<IEventStore>(_ =>
            {
                return defaultStorerOfChannel;
            });


            services.AddSingleton<IEventPublishManager, EventPublishManager>();
            services.AddSingleton<IEventSubscribeManager, EventSubscribeManager>();


            eventBusOptionsBuilder.Build(services);

            // 通过工厂模式创建
            services.AddHostedService(serviceProvider =>
            {
                // 创建事件总线后台服务对象
                var eventBusHostedService = ActivatorUtilities.CreateInstance<EventBusHostBackgroundService>(
                    serviceProvider
                    , eventBusOptionsBuilder.EnabledLogOut);


                var unhandleException = eventBusOptionsBuilder.UnhandleException;
                if (unhandleException != default)
                {
                    eventBusHostedService.UnhandleException += unhandleException;
                }

                return eventBusHostedService;
            });

            return services;
        }
    }
}
